package com.example.micro.spider.controller;

import java.awt.Color;
import java.awt.Dimension;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.example.micro.spider.mapper.DoubanFwGroupMapper;
import com.example.micro.spider.mapper.XhsInfoMapper;
import com.example.micro.spider.model.DoubanFwGroup;
import com.example.micro.spider.model.DoubanFwGroupExample;
import com.example.micro.spider.model.XhsInfo;
import com.example.micro.spider.pojo.XhsData;
import com.example.micro.spider.pojo.XhsItem;
import com.example.micro.spider.pojo.XhsResult;
import com.kennycason.kumo.CollisionMode;
import com.kennycason.kumo.WordCloud;
import com.kennycason.kumo.WordFrequency;
import com.kennycason.kumo.bg.CircleBackground;
import com.kennycason.kumo.bg.PixelBoundryBackground;
import com.kennycason.kumo.font.KumoFont;
import com.kennycason.kumo.font.scale.SqrtFontScalar;
import com.kennycason.kumo.nlp.FrequencyAnalyzer;
import com.kennycason.kumo.nlp.tokenizers.ChineseWordTokenizer;
import com.kennycason.kumo.palette.ColorPalette;
import com.vdurmont.emoji.EmojiParser;

/**
 * @author Code Farmer
 * @create 2021/5/12 4:25 下午
 */
@RestController
public class IndexController {

    private final String doubanUrl = "https://www.douban.com/group/692739/discussion?start=%s&type=new";

    @Autowired
    private XhsInfoMapper xhsInfoMapper;

    @Autowired
    private DoubanFwGroupMapper doubanFwGroupMapper;

    private final SimpleDateFormat format =
            new SimpleDateFormat("yyyy-MM-dd");
    private final SimpleDateFormat timeFormat =
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @SuppressWarnings("checkstyle:MagicNumber")
    @GetMapping("/douban")
    public String douban() {
        try {
            for (int i = 0; i < 50000; i += 25) {
                getEveryPageHtml(i);
            }
            return null;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "success";
    }

    @GetMapping("/douban/word/cloud")
    public String doubanWordCloud() throws IOException {
        List<DoubanFwGroup> doubanFwGroupList = doubanFwGroupMapper.selectByExample(new DoubanFwGroupExample());
        return createWordCloud(doubanFwGroupList.stream()
                .map(DoubanFwGroup::getTitle).collect(Collectors.toList()));
    }

    private void getEveryPageHtml(int index) throws IOException {
        Document document = Jsoup.connect(String.format(doubanUrl, index))
                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
                .header("Accept-Encoding", "gzip, deflate, sdch")
                .header("Accept-Language", "zh-CN,zh;q=0.8")
                .header("User-Agent",
                        "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0"
                                + ".2883.87 Safari/537.36")
                .get();
        Elements elementsTable = document.getElementsByClass("olt").select("table");
        if (elementsTable.isEmpty()) {
            System.out.println("elementsTable is null,index:" + index);
            return;
        }
        Element firstElementsTable = elementsTable.first();
        if (firstElementsTable == null) {
            System.out.println("firstElementsTable is null,index:" + index);
            return;
        }
        Elements elementsTdEqClass = firstElementsTable.getElementsByClass("title").select("td");
        if (elementsTdEqClass.isEmpty()) {
            System.out.println("elementsTdEqClass is null,index:" + index);
            return;
        }
        for (int j = 0; j < elementsTdEqClass.size(); j++) {
            String text = elementsTdEqClass.get(j).select("a").first().text();
            System.out.println(text);
            DoubanFwGroup doubanFwGroup = new DoubanFwGroup();
            doubanFwGroup.setTitle(EmojiParser.parseToAliases(text));
            doubanFwGroup.setCreateTime(System.currentTimeMillis());
            doubanFwGroupMapper.insertSelective(doubanFwGroup);
        }
    }

    @SuppressWarnings("checkstyle:MagicNumber")
    private String createWordCloud(List<String> words) throws IOException {
        FrequencyAnalyzer frequencyAnalyzer = new FrequencyAnalyzer();
        frequencyAnalyzer.setWordFrequenciesToReturn(600);
        frequencyAnalyzer.setMinWordLength(2);

        // 引入中文解析器
        frequencyAnalyzer.setWordTokenizer(new ChineseWordTokenizer());

        final List<WordFrequency> wordFrequencyList = frequencyAnalyzer.load(words);

        // 设置图片分辨率
        Dimension dimension = new Dimension(1269, 1350);
        // 此处的设置采用内置常量即可，生成词云对象
        WordCloud wordCloud = new WordCloud(dimension, CollisionMode.PIXEL_PERFECT);
        java.awt.Font font = new java.awt.Font("STSong-Light", 2, 40);
        wordCloud.setKumoFont(new KumoFont(font));
        wordCloud.setPadding(2);
        wordCloud.setColorPalette(
                new ColorPalette(new Color(0xed1941), new Color(0xf26522), new Color(0x845538), new Color(0x8a5d19),
                        new Color(0x7f7522), new Color(0x5c7a29), new Color(0x1d953f), new Color(0x007d65),
                        new Color(0x65c294)));
        wordCloud.setBackground(new CircleBackground(200));
        wordCloud.setFontScalar(new SqrtFontScalar(10, 40));
        //        wordCloud.setBackgroundColor(new Color(255, 255, 255));
        wordCloud.setBackground(new PixelBoundryBackground(
                "/Users/liubolun/IdeaProjects/alibaba-cloud-demo/micro-spider/src/main/resources/static/0413_1.png"));
        // 生成词云
        wordCloud.build(wordFrequencyList);
        OutputStream output = new ByteArrayOutputStream();
        wordCloud.writeToStream("png", output);
        byte[] outputByte = ((ByteArrayOutputStream) output).toByteArray();
        return org.apache.commons.codec.binary.Base64.encodeBase64String(outputByte);
    }

    public static void main(String[] args) throws URISyntaxException {
        URI uri = new URI("https://cdnfile.corp.kuaishou"
                + ".com/kc/files/a/csc-center-internal/RkJfMTI5NTk0NDkyOF8xNjU2NDE3ODI0NjU0X00zc3c=.jpg");
        System.out.println(uri.getHost());
        //        new IndexController().douban();
    }

    @GetMapping("/index")
    public String index() {
        this.load("漫画腿");
        return "success";
    }

    public void load(String keyword) {
        String filePath = "/Users/didi/Desktop/search/" + keyword;
        loadOne(new File(filePath), keyword);
    }

    /**
     * 递归获取类文件
     */
    private void loadOne(File fileParent, String keyword) {
        if (fileParent.isDirectory()) {
            File[] childrenFiles = fileParent.listFiles();
            if (childrenFiles == null || childrenFiles.length == 0) {
                return;
            }
            for (File child : childrenFiles) {
                if (child.isDirectory()) {
                    //如果是个文件夹，就继续调用该方法
                    loadOne(child, keyword);
                } else {
                    if (child.isHidden()) {
                        continue;
                    }
                    String path = child.getPath();
                    System.out.println(path);
                    String jsonStr = readFileContent(path);
                    System.out.println(jsonStr);
                    XhsResult xhsResult = JSONObject.parseObject(jsonStr, XhsResult.class);
                    this.insertData(xhsResult, keyword);
                }
            }
        }
    }

    private void insertData(XhsResult xhsResult, String keyword) {

        if (xhsResult == null) {
            return;
        }
        XhsData data = xhsResult.getData();
        if (data == null) {
            return;
        }
        List<XhsItem> items = data.getItems();
        if (StringUtils.isEmpty(items)) {
            return;
        }
        for (int i = 0; i < items.size(); i++) {
            XhsItem xhsItem = items.get(i);
            if (xhsItem == null || xhsItem.getNote() == null) {
                continue;
            }
            XhsInfo xhsInfo = new XhsInfo();
            xhsInfo.setXhsId(xhsItem.getNote().getId());
            xhsInfo.setCreateTime(xhsItem.getNote().getTimestamp());
            String desc = xhsItem.getNote().getDesc();
            xhsInfo.setDescription(removeNonBmpUnicode(desc));
            xhsInfo.setLikedCount(xhsItem.getNote().getLiked_count());
            xhsInfo.setModelType(xhsItem.getModel_type());
            String title = xhsItem.getNote().getTitle();
            xhsInfo.setTitle(removeNonBmpUnicode(title));
            xhsInfo.setCategory(calCategory(title, desc));

            String nickname = xhsItem.getNote().getUser().getNickname();
            xhsInfo.setNickname(removeNonBmpUnicode(nickname));

            xhsInfo.setUserId(xhsItem.getNote().getUser().getUserid());

            Date date = new Date((long) xhsItem.getNote().getTimestamp() * 1000);
            xhsInfo.setDate(format.format(date));
            xhsInfo.setCreateTimeC(timeFormat.format(date));
            xhsInfo.setKeyWord(keyword);

            xhsInfoMapper.insertSelective(xhsInfo);

        }
    }

    public String calCategory(String title, String desc) {
        if (title.contains("挑战") || desc.contains("挑战")) {
            return "挑战";
        }
        if (title.contains("试") || desc.contains("试")) {
            return "挑战";
        }
        if (title.contains("同款") || desc.contains("同款")) {
            return "挑战";
        }
        if (title.contains("打卡") || desc.contains("打卡")) {
            return "挑战";
        }
        if (title.contains("健康") || desc.contains("健康")) {
            return "健康";
        }
        if (title.contains("危害") || desc.contains("危害")) {
            return "健康";
        }
        if (title.contains("伤") || desc.contains("伤")) {
            return "健康";
        }
        if (title.contains("教程") || desc.contains("教程")) {
            return "教程";
        }
        if (title.contains("练") || desc.contains("练")) {
            return "教程";
        }
        return "其他";
    }

    public static String readFileContent(String fileName) {
        File file = new File(fileName);
        BufferedReader reader = null;
        StringBuilder stringBuffer = new StringBuilder();
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempStr;
            while ((tempStr = reader.readLine()) != null) {
                stringBuffer.append(tempStr);
            }
            reader.close();
            return stringBuffer.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return stringBuffer.toString();
    }

    public String removeNonBmpUnicode(String str) {
        if (str == null) {
            return null;
        }
        str = str.replaceAll("[^\\u0000-\\uFFFF]", "");
        return str;
    }


}
